package com.zim.aliot.aspect;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.aliyuncs.utils.StringUtils;
import com.google.gson.Gson;
import com.zim.aliot.config.VerifyConfig;
import com.zim.aliot.enums.ResultEnum;
import com.zim.aliot.exception.LcxApiException;
import com.zim.aliot.vo.VehicleVO;

import lombok.extern.slf4j.Slf4j;

@Aspect
@Component
@Slf4j
public class AuthorizeAspect {
	
	@Autowired
	private VerifyConfig verifyConfig;
	
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    @Autowired
    private Gson gson;
	
	@Pointcut("execution(public * com.zim.aliot.controller.*.*(..)) && !execution(public * com.zim.aliot.controller.IndexController.*(..))")
	public void verify() {}
	
	@Before("verify()")
	public void doVerify() {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        
        String ip = request.getHeader("Ip");
        String timeStamp = request.getHeader("Time-Stamp");
        String seqId = request.getHeader("Seq-Id");
        String sign = request.getHeader("Sign");
        
        String stringSign = createSign(verifyConfig.getUserName(),verifyConfig.getKey(),ip,seqId,timeStamp);
        if(null==sign || !sign.equals(stringSign)) {
        	log.error("[ 登录验证失败 ]:{}",stringSign);
//        	throw new LcxApiException(ResultEnum.LOGIN_FAIL);
        }
        
	}
	
	@Pointcut("execution(public * com.zim.aliot.controller.CommandController.*(..))")
	public void netWork() {}
	
	@Before("netWork()")
	public void doNetWork() {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String carId = request.getParameter("car_unique_id");
        if(null==carId) {
        	log.error("[车架号]:{}",carId);
//        	throw new LcxApiException(ResultEnum.PARAM_ERROR);
        }
        String stringVehicleVo = stringRedisTemplate.opsForValue().get(carId);
        if(StringUtils.isEmpty(stringVehicleVo)) {
        	log.error("[ 车机数据为空 ]:{}",stringVehicleVo);
//        	throw new LcxApiException(ResultEnum.OFF_LINE);
        }else {
        	VehicleVO vehicleVO = gson.fromJson(stringVehicleVo, VehicleVO.class);
        	if(0 == vehicleVO.getNetwork_status()) {
        		log.error("[ 车机离线 ]:{}",vehicleVO.getNetwork_status());;
//        		throw new LcxApiException(ResultEnum.OFF_LINE);
        	}
        }
        
        
	}
	
	/**
     * 生成签名，
     * @param seqId
     * @param timeStamp
     * @return
     */
    protected  String createSign(String userName,String key ,String ip,String seqId, String timeStamp) {
        //第一步：对参数按照key=value的格式，并按照参数名ASCII字典序排序如下
        //第二步：拼接API密钥
        String sign = "user_name=" + userName
                + "&ip=" + ip
                + "&time_stamp=" + timeStamp
                + "&seq_id=" + seqId
                + "&key=" + key;
        //第三部：md5加密，并转化为大写
        try {
            return DigestUtils.md5DigestAsHex(sign.getBytes("UTF-8")).toUpperCase();
        } catch (UnsupportedEncodingException e) {
            log.error("[MD5]:{}",e.getMessage());
            return null;
        }
      
    }
}
